Solving 10385 - Duathlon (Ternary search)
[andmenj-acm.git] / 11448 - Who said crisis / 11448.2.cpp
blobd5e087c45fb532655d8c3a05b52a566c2d593cb1
1 #include <stdio.h>
2 #include <math.h>
3 #include <iostream>
5 using namespace std;
7 #define MAXDIGITS 10001 /* maximum length bignum */
9 #define PLUS 1 /* positive sign bit */
10 #define MINUS -1 /* negative sign bit */
12 typedef struct {
13 char digits[MAXDIGITS]; /* represent the number */
14 int signbit; /* 1 if positive, -1 if negative */
15 int lastdigit; /* index of high-order digit */
16 } bignum;
19 void subtract_bignum(bignum *a, bignum *b, bignum *c);
20 void zero_justify(bignum *n);
21 int compare_bignum(bignum *a, bignum *b);
23 void print_bignum(bignum *n)
25 int i;
27 if (n->signbit == MINUS) printf("-");
28 for (i=n->lastdigit; i>=0; i--)
29 printf("%c",'0'+ n->digits[i]);
31 printf("\n");
34 void int_to_bignum(int s, bignum *n)
36 int i; /* counter */
37 int t; /* int to work with */
39 if (s >= 0) n->signbit = PLUS;
40 else n->signbit = MINUS;
42 for (i=0; i<MAXDIGITS; i++) n->digits[i] = (char) 0;
44 n->lastdigit = -1;
46 t = abs(s);
48 while (t > 0) {
49 n->lastdigit ++;
50 n->digits[ n->lastdigit ] = (t % 10);
51 t = t / 10;
54 if (s == 0) n->lastdigit = 0;
57 void string_to_bignum(const string &s, bignum *n)
59 int i; /* counter */
61 if (s.size() == 0){
62 int_to_bignum(0, n);
63 return;
66 if (s[0] != '-') n->signbit = PLUS;
67 else n->signbit = MINUS;
69 for (i=0; i<MAXDIGITS; i++) n->digits[i] = (char) 0;
71 n->lastdigit = -1;
73 int len = s.size();
74 for (i=0; i<len; ++i){
75 n->lastdigit++;
76 n->digits[n->lastdigit] = s[i] - '0';
81 void initialize_bignum(bignum *n)
83 int_to_bignum(0,n);
87 int max(int a, int b)
89 if (a > b) return(a); else return(b);
92 /* c = a +-/* b; */
94 void add_bignum(bignum *a, bignum *b, bignum *c)
96 int carry; /* carry digit */
97 int i; /* counter */
99 initialize_bignum(c);
101 if (a->signbit == b->signbit) c->signbit = a->signbit;
102 else {
103 if (a->signbit == MINUS) {
104 a->signbit = PLUS;
105 subtract_bignum(b,a,c);
106 a->signbit = MINUS;
107 } else {
108 b->signbit = PLUS;
109 subtract_bignum(a,b,c);
110 b->signbit = MINUS;
112 return;
115 c->lastdigit = max(a->lastdigit,b->lastdigit)+1;
116 carry = 0;
118 for (i=0; i<=(c->lastdigit); i++) {
119 c->digits[i] = (char) (carry+a->digits[i]+b->digits[i]) % 10;
120 carry = (carry + a->digits[i] + b->digits[i]) / 10;
123 zero_justify(c);
127 void subtract_bignum(bignum *a, bignum *b, bignum *c)
129 int borrow; /* has anything been borrowed? */
130 int v; /* placeholder digit */
131 int i; /* counter */
133 initialize_bignum(c);
135 if ((a->signbit == MINUS) || (b->signbit == MINUS)) {
136 b->signbit = -1 * b->signbit;
137 add_bignum(a,b,c);
138 b->signbit = -1 * b->signbit;
139 return;
142 if (compare_bignum(a,b) == PLUS) {
143 subtract_bignum(b,a,c);
144 c->signbit = MINUS;
145 return;
148 c->lastdigit = max(a->lastdigit,b->lastdigit);
149 borrow = 0;
151 for (i=0; i<=(c->lastdigit); i++) {
152 v = (a->digits[i] - borrow - b->digits[i]);
153 if (a->digits[i] > 0)
154 borrow = 0;
155 if (v < 0) {
156 v = v + 10;
157 borrow = 1;
160 c->digits[i] = (char) v % 10;
163 zero_justify(c);
166 int compare_bignum(bignum *a, bignum *b)
168 int i; /* counter */
170 if ((a->signbit == MINUS) && (b->signbit == PLUS)) return(PLUS);
171 if ((a->signbit == PLUS) && (b->signbit == MINUS)) return(MINUS);
173 if (b->lastdigit > a->lastdigit) return (PLUS * a->signbit);
174 if (a->lastdigit > b->lastdigit) return (MINUS * a->signbit);
176 for (i = a->lastdigit; i>=0; i--) {
177 if (a->digits[i] > b->digits[i]) return(MINUS * a->signbit);
178 if (b->digits[i] > a->digits[i]) return(PLUS * a->signbit);
181 return(0);
184 void zero_justify(bignum *n)
186 while ((n->lastdigit > 0) && (n->digits[ n->lastdigit ] == 0))
187 n->lastdigit --;
189 if ((n->lastdigit == 0) && (n->digits[0] == 0))
190 n->signbit = PLUS; /* hack to avoid -0 */
194 void digit_shift(bignum *n, int d) /* multiply n by 10^d */
196 int i; /* counter */
198 if ((n->lastdigit == 0) && (n->digits[0] == 0)) return;
200 for (i=n->lastdigit; i>=0; i--)
201 n->digits[i+d] = n->digits[i];
203 for (i=0; i<d; i++) n->digits[i] = 0;
205 n->lastdigit = n->lastdigit + d;
210 void multiply_bignum(bignum *a, bignum *b, bignum *c)
212 bignum row; /* represent shifted row */
213 bignum tmp; /* placeholder bignum */
214 int i,j; /* counters */
216 initialize_bignum(c);
218 row = *a;
220 for (i=0; i<=b->lastdigit; i++) {
221 for (j=1; j<=b->digits[i]; j++) {
222 add_bignum(c,&row,&tmp);
223 *c = tmp;
225 digit_shift(&row,1);
228 c->signbit = a->signbit * b->signbit;
230 zero_justify(c);
234 void divide_bignum(bignum *a, bignum *b, bignum *c)
236 bignum row; /* represent shifted row */
237 bignum tmp; /* placeholder bignum */
238 int asign, bsign; /* temporary signs */
239 int i,j; /* counters */
241 initialize_bignum(c);
243 c->signbit = a->signbit * b->signbit;
245 asign = a->signbit;
246 bsign = b->signbit;
248 a->signbit = PLUS;
249 b->signbit = PLUS;
251 initialize_bignum(&row);
252 initialize_bignum(&tmp);
254 c->lastdigit = a->lastdigit;
256 for (i=a->lastdigit; i>=0; i--) {
257 digit_shift(&row,1);
258 row.digits[0] = a->digits[i];
259 c->digits[i] = 0;
260 while (compare_bignum(&row,b) != PLUS) {
261 c->digits[i] ++;
262 subtract_bignum(&row,b,&tmp);
263 row = tmp;
267 zero_justify(c);
269 a->signbit = asign;
270 b->signbit = bsign;
275 main()
277 string a, b;
278 int n;
279 cin >> n;
280 while (n--){
281 cin >> a >> b;
282 reverse(a.begin(), a.end());
283 reverse(b.begin(), b.end());
284 bignum n1,n2,n3;
285 string_to_bignum(a, &n1);
286 string_to_bignum(b, &n2);
287 subtract_bignum(&n1, &n2, &n3);
288 print_bignum(&n3);
290 return 0;